home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 1.iso / HENSA / MISC / SHELL.ARC / Shell / Sources / c / GFX < prev    next >
Text File  |  1994-11-21  |  8KB  |  353 lines

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <time.h>
  4.  
  5. #include "DeskLib:GFX.h"
  6. #include "DeskLib:Coord.h"
  7. #include "DeskLib:WimpSWIs.h"
  8. #include "DeskLib:Error.h"
  9. #include "DeskLib:Window.h"
  10. #include "DeskLib:Event.h"
  11.  
  12. #include "Shell.Extra.h"
  13. #include "Shell.SafeAlloc.h"
  14. #include "Shell.PlotIcon.h"
  15. #include "Shell.Redraw2.h"
  16.  
  17.  
  18.  
  19. Shell_windblock    Shell_windows[ Shell_MAXWINDS];
  20. int Shell_numwinds = 0;
  21.  
  22.  
  23.  
  24.  
  25.  
  26.  
  27.  
  28.  
  29. void Shell_WindRedraw2( wimp_rect *workrect, Shell_convertpoint convert, Shell_windblock *wind)
  30.     /* This takes a workarea rectangle and redraws     */
  31.     /* any shell-rectangles in Shell window 'wind'    */
  32.     /* which overlap with it.            */
  33. {
  34. Shell_rectblock *rectblock;
  35.  
  36. for    (
  37.     rectblock = LinkList_FirstItem( &wind->anchor);
  38.     rectblock;
  39.     rectblock = LinkList_NextItem( &rectblock->header)
  40.     )
  41.  
  42.     {
  43.     if ( rectblock->plot_icon)    {
  44.         /* The rect should be plotted as an icon - e.g. for a border, and a     */
  45.         /* background colour. Also, we will set the grapics colour to the icon    */
  46.         /* foreground colour here.                        */
  47.  
  48.         if ( Coord_RectsOverlap( workrect, &rectblock->icon.workarearect))
  49.             Shell_PlotIcon( &rectblock->icon, convert);
  50.             /* Shell_PlotIcon is identical to Wimp_PlotIcon, but         */
  51.             /* only sends 16 bit coors to Wimp_PlotIcon, so arbitarily    */
  52.             /* sized icons can be plotted                    */
  53.  
  54.         Wimp_SetColour( rectblock->icon.flags.data.foreground);
  55.  
  56.         }
  57.  
  58.     if ( Coord_RectsOverlap( workrect, &rectblock->rect))    {
  59.  
  60.         /* Set things up so the redrawer only has to work in coors relative     */
  61.         /* to this rectblock's origin.                        */
  62.  
  63.         Shell_convertpoint    localconvert;
  64.         wimp_rect        localredrawrect;
  65.         wimp_point        localsize;
  66.  
  67.         localsize.x = rectblock->rect.max.x - rectblock->rect.min.x;
  68.         localsize.y = rectblock->rect.max.y - rectblock->rect.min.y;
  69.  
  70.         localconvert.x = convert.x + rectblock->rect.min.x;
  71.         localconvert.y = convert.y + rectblock->rect.min.y;
  72.  
  73.         localredrawrect.min.x = workrect->min.x - rectblock->rect.min.x;
  74.         localredrawrect.max.x = workrect->max.x - rectblock->rect.min.x;
  75.         localredrawrect.min.y = workrect->min.y - rectblock->rect.min.y;
  76.         localredrawrect.max.y = workrect->max.y - rectblock->rect.min.y;
  77.  
  78.         (*rectblock->redrawer)
  79.             (
  80.             localconvert,
  81.             localsize,
  82.             rectblock->reference,
  83.             &localredrawrect
  84.             );
  85.         }
  86.     }
  87.  
  88. return;
  89.        }
  90.  
  91.  
  92.  
  93.  
  94.  
  95.  
  96.  
  97.  
  98.  
  99.  
  100.  
  101.  
  102.  
  103.  
  104. static BOOL    Shell_WindRedraw( event_pollblock *event, void *reference)
  105.  
  106. {    Shell_windblock        *info    = (Shell_windblock *) reference;
  107.     Shell_convertpoint    convert;
  108.     wimp_rect        workrect;
  109.     window_redrawblock    redrawblock;
  110.     BOOL            more;
  111.  
  112. redrawblock.window = event->data.openblock.window;
  113. Wimp_RedrawWindow( &redrawblock, &more);
  114.  
  115. convert.x = redrawblock.rect.min.x - redrawblock.scroll.x;
  116. convert.y = redrawblock.rect.max.y - redrawblock.scroll.y;
  117.  
  118. for    (
  119.     ;
  120.     more;
  121.     Wimp_GetRectangle( &redrawblock, &more)
  122.     )
  123.  
  124.     {
  125.     workrect = redrawblock.cliprect;
  126.     Shell_ConvertRectToWorkarea( &workrect, convert);
  127.  
  128.     Shell_WindRedraw2( &workrect, convert, info);
  129.         /* Most of the work is in this separate fn so that it can be called     */
  130.         /* independantly within a fn which temporaraly redirects output to a     */
  131.         /* sprite - see PlainRect.c                        */
  132.  
  133.     }
  134.  
  135. return TRUE;
  136. }
  137.  
  138.  
  139.  
  140.  
  141.  
  142.  
  143.  
  144.  
  145.  
  146. Shell_windblock    *Shell_OpenWindow( void)
  147. {
  148.     Shell_windblock    *info;
  149.  
  150. if ( Shell_numwinds == Shell_MAXWINDS) Error_ReportFatal( 1, Error_PLACE "Too many GFX windows");
  151.     /* Should change the window storage to use a linked list (like each window's rect-list.    */
  152.  
  153. Shell_numwinds++;
  154. info = &Shell_windows[Shell_numwinds-1];
  155. info->window = Window_CreateAndShow( "ShellWindow", /*maxtitlesize*/ 0, open_NEARLAST);
  156.  
  157. if ( info->window == 0)
  158.     Error_ReportFatal( 0, Error_PLACE "Shell_OpenGFXWindow -couldn't find 'ShellWindow' in templates");
  159.     /* This error-detection doesn't work - Window_CreateShow returns a non-zero window    */
  160.     /* handle even if the templates don't have the window. This can cause problems!        */
  161.  
  162. info->numrects = 0;
  163. LinkList_Init( &info->anchor);
  164.  
  165. Event_Claim( event_REDRAW, info->window, event_ANY, Shell_WindRedraw, (void *) info);
  166.  
  167. return info;
  168. }
  169.  
  170.  
  171.  
  172.  
  173.  
  174.  
  175.  
  176. Shell_rectblock    *Shell_AddRectangle(
  177.     Shell_windblock    *w,
  178.     const wimp_rect    *rect,
  179.     Shell_redrawer    redrawfn,
  180.     const void    *reference
  181.     )
  182. /* This creates a 'plain' rectangle in a window - it has no border, and the background colour    */
  183. /* will be the same as the background of the window. To give the rect a border and back/fore-    */
  184. /* colours, use Shell_MakeRectIcon.                                */
  185.  
  186. {
  187.     Shell_rectblock    *r;
  188.  
  189. if ( (w-Shell_windows >= Shell_MAXWINDS) || (w-Shell_windows < 0))
  190.     Error_ReportFatal( 1, Error_PLACE "Invalid Shell_windblock in Shell_AddRectangle, '%p'", w);
  191.  
  192. w->numrects++;
  193. r = Shell_SafeMalloc( sizeof( Shell_rectblock));
  194. LinkList_AddToTail( &w->anchor, &r->header);
  195.  
  196. r->update_time        = 0;        /* minimum time between rect redraws        */
  197. r->last_update        = 0;
  198. r->rect            = *rect;    /* rectangle which encloses the rect's data    */
  199. r->icon.workarearect    = *rect;    /* border around the rect.            */
  200. r->redrawer        = redrawfn;
  201. r->saver        = NULL;        /* NULL or a valid rect saver            */
  202. r->ramsaver        = NULL;        /* NULL or a valid rect ramsaver        */
  203. r->size            = 256;        /* Default size.                */
  204. r->filetype        = 0xfff;    /* Default filetype is text.            */
  205. r->reference        = (void *) reference;
  206. r->window        = w->window;
  207. r->plot_icon        = FALSE;    /* This is a plain rect.            */
  208.  
  209.  
  210. Shell_CheckWindSizeAndRedraw( w->window, &r->rect);
  211.     /* This resizes the window if nesesary so that it contains the     */
  212.     /* rectangle. Hence the window automatically expands to contain    */
  213.     /* any rects added to it.                    */
  214.  
  215. return r;
  216. }
  217.  
  218.  
  219.  
  220.  
  221.  
  222. Shell_rectblock    *Shell_AddRectangle2(
  223.     Shell_windblock *w,
  224.     int xmin, int ymin, int xmax, int ymax,
  225.     Shell_redrawer redrawfn,
  226.     const void *reference
  227.     )
  228. {
  229.     wimp_rect rect;
  230.  
  231. rect.min.x = xmin; rect.min.y = ymin;
  232. rect.max.x = xmax; rect.max.y = ymax;
  233. return Shell_AddRectangle( w, &rect, redrawfn, reference);
  234. }
  235.  
  236.  
  237.  
  238.  
  239. Shell_rectblock    *Shell_AddRectangle3(
  240.     Shell_windblock *w,
  241.     int xmin, int ymin,
  242.     int xsize, int ysize,
  243.     Shell_redrawer redrawfn,
  244.     const void *reference
  245.     )
  246. {
  247.     wimp_rect rect;
  248.  
  249. rect.min.x = xmin;    rect.max.x = xmin + xsize;
  250. rect.min.y = ymin;    rect.max.y = ymin + ysize;
  251. return Shell_AddRectangle( w, &rect, redrawfn, reference);
  252. }
  253.  
  254.  
  255.  
  256.  
  257.  
  258.  
  259. void    Shell_ForceRectRedraw( Shell_rectblock *r)
  260. {    window_redrawblock block;
  261. r->last_update    = clock();
  262. block.window    = r->window;
  263. block.rect    = r->rect;
  264. Wimp_ForceRedraw( &block);    /* The actual redraw will be done when the Wimp sends     */
  265.                 /* event_REDRAW on the next Shell/Event_Poll.        */
  266. return;
  267. }
  268.  
  269.  
  270. void    Shell_ForceRectRedrawSlow( Shell_rectblock *r)
  271. /*    This only ForceRedraws a rectangle if the    */
  272. /*    last redraw was a sufficiently long time ago    */
  273. {
  274.     clock_t    t    = clock();
  275. if ( t - r->last_update >= r->update_time)    {
  276.     r->last_update    = t;
  277.     Shell_ForceRectRedraw( r);
  278.     }
  279. return;
  280. }
  281.  
  282.  
  283.  
  284.  
  285.  
  286. void Shell_ForceRectUpdate( Shell_rectblock *r)
  287. /*    This routine redraws a rectangle without clearing it    */
  288. /*    to the background colour. Use for animation etc.    */
  289. /*    The redraw loop occurs imediately, without polling    */
  290. /*    the Wimp.                        */
  291. {
  292.     window_redrawblock    redrawblock;
  293.     Shell_convertpoint    convert;
  294.     wimp_rect        workrect;
  295.     BOOL            more;
  296.     wimp_point        rectsize;
  297.  
  298. rectsize.x = r->rect.max.x - r->rect.min.x;
  299. rectsize.y = r->rect.max.y - r->rect.min.y;
  300.  
  301. redrawblock.window    = r->window;
  302. redrawblock.rect    = r->rect;
  303.  
  304. Wimp_UpdateWindow( &redrawblock, &more);
  305.  
  306. convert.x = redrawblock.rect.min.x - redrawblock.scroll.x + r->rect.min.x;
  307. convert.y = redrawblock.rect.max.y - redrawblock.scroll.y + r->rect.min.y;
  308.  
  309.  
  310. for    (
  311.     ;
  312.     more;
  313.     Wimp_GetRectangle( &redrawblock, &more)
  314.     )
  315.  
  316.     {
  317.     workrect.max.x = redrawblock.cliprect.max.x - convert.x;
  318.     workrect.min.x = redrawblock.cliprect.min.x - convert.x;
  319.     workrect.max.y = redrawblock.cliprect.max.y - convert.y;
  320.     workrect.min.y = redrawblock.cliprect.min.y - convert.y;
  321.  
  322.     ( *(r->redrawer) ) ( convert, rectsize, r->reference, &workrect);
  323.     /* Call the redrawing function for the rectangle */
  324.  
  325.     }
  326. }
  327.  
  328.  
  329.  
  330.  
  331. void    Shell_ForceRectUpdateSlow( Shell_rectblock *r)
  332. /*    This only ForceUpdates a rectangle if the    */
  333. /*    last redraw was a sufficiently long time ago    */
  334. {
  335.     clock_t    t    = clock();
  336. if ( t - r->last_update >= r->update_time)    {
  337.     r->last_update    = t;
  338.     Shell_ForceRectUpdate( r);
  339.     }
  340. return;
  341. }
  342.  
  343.  
  344.  
  345.  
  346.  
  347. void Shell_SetWindowTitle( window_handle window, char *text)
  348.     /* There used to be code here, but DeskLib 2.04 has a function built in which actually    */
  349.     /* works properly!                                    */
  350. {
  351. Window_SetTitle( window, text);
  352. }
  353.